//
// Created by Tony on 2024/6/13.
//

#ifndef COMMON_OP_CODE_H
#define COMMON_OP_CODE_H

#include <cstdint>

namespace Common {

enum class OpCode : uint8_t {
    NOP = 0, // 无操作

    LOAD_I,  // 将16bit立即数加载到栈顶
    LOAD_K,  // 从常量池中加载index对应的值到栈顶
    LOAD_V,  // 加载栈上index对应的变量到栈顶
    STORE_V, // 将栈顶的变量保存到栈上对应index的位置

    NEW, // 创建index对应的ClassRef的实例

    GET_FIELD,
    PUT_FIELD, // 与Java实现不同，this在栈上位于参数列表上面
    GET_STATIC,
    PUT_STATIC,

    INVOKE_STATIC,  // 调用类的静态方法
    INVOKE_SPECIAL, // 调用实例的初始化方法和私有方法，与Java实现不同，this在栈上位于参数列表上面
    INVOKE_VIRTUAL, // 调用实例方法，区别于INVOKE_SPECIAL，因为实例方法可被复写，因此方法查找逻辑与其不同，与Java实现不同，this在栈上位于参数列表上面

    RETURN,   // 函数返回，无返回值
    RETURN_V, // 函数返回，有返回值

    ADD, // 将栈顶的两个元素相加保存到栈顶
    SUB, // 将栈顶的两个元素相减保存到栈顶
    MUL, // 将栈顶的两个元素相乘保存到栈顶
    DIV, // 将栈顶的两个元素相除保存到栈顶

    EQ, // 将栈顶的两个元素比较，如果 left(top-2) == right(top-1)，则将1压入栈顶，否则压入0
    NE, // 将栈顶的两个元素比较，如果 left(top-2) != right(top-1)，则将1压入栈顶，否则压入0
    LT, // 将栈顶的两个元素比较，如果 left(top-2) < right(top-1)，则将1压入栈顶，否则压入0
    LE, // 将栈顶的两个元素比较，如果 left(top-2) <= right(top-1)，则将1压入栈顶，否则压入0
    GT, // 将栈顶的两个元素比较，如果 left(top-2) > right(top-1)，则将1压入栈顶，否则压入0
    GE, // 将栈顶的两个元素比较，如果 left(top-2) >= right(top-1)，则将1压入栈顶，否则压入0

    IF_TRUE,  // 栈顶元素为true(1)跳转 ( pc + offset )
    IF_FALSE, // 栈顶元素为false(0)跳转 ( pc + offset )

    JMP, // 无条件跳转到 ( pc + offset ), pc为当前正在执行的执行地址

    NO_USE = 0xFF
};

} // namespace Common

#endif // COMMON_OP_CODE_H
